﻿using System;
using Microsoft.Maps.MapControl;
using System.Windows;
using System.Collections.Generic;
using MyFloridaHouse.ServiceConn.DistrBldrSvcRef;
using MyFloridaHouse.libSvUtilities.Logging;
using MyFloridaHouse.libSvOpenDistricts.Criteria;

namespace MyFloridaHouse.libSvOpenDistricts.DataService
{
    public delegate void ServiceDALGetLayerRegionsShapesInViewCompletedEventHandler(LayerRegionsShapesSTO args);

    public struct PendingGetLayerRegionsShapesInViewRequest
    {
        public double iZoomLevel;
        public int layerID;
        public LocationRect viewWindow;
    }

    public partial class ServiceDAL
    {
        public static event ServiceDALGetLayerRegionsShapesInViewCompletedEventHandler GetLayerRegionsShapesInViewCompleted;

        public void GetLayerRegionsShapesInView(double iZoomLevel, int layerID, LocationRect viewWindow)
        {
            try
            {
                if (getGetLayerRegionsShapesInViewCount(layerID) > 0)
                {
                    PendingGetLayerRegionsShapesInViewRequest rqst = new PendingGetLayerRegionsShapesInViewRequest();
                    rqst.iZoomLevel = iZoomLevel;
                    rqst.layerID = layerID;
                    rqst.viewWindow = viewWindow;
                    addGetLayerRegionsShapesInViewPendingRequest(layerID, rqst);
                }
                else
                {
                    //MyDistrictBuilderServiceClient proxy = new MyDistrictBuilderServiceClient(myRelativeBinding, myRelativeCensusDataServiceAddress);
					var proxy = new DistrBldrClient(_relativeBindingName);
                    proxy.GetLayerRegionsShapesInViewCompleted += ServiceGetLayerRegionsShapesInViewCompleted;
                    proxy.GetLayerRegionsShapesInViewAsync(iZoomLevel, layerID, viewWindow.North, viewWindow.East, viewWindow.South, viewWindow.West);
                    incrementGetLayerRegionsShapesInViewActiveCount(layerID);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void ServiceGetLayerRegionsShapesInViewCompleted(object sender, GetLayerRegionsShapesInViewCompletedEventArgs args)
        {
            decrementGetLayerRegionsShapesInViewActiveCount(args.Result.layerID);
            if (!IsError("GetLayerRegionsShapesInViewCompleted", args.Error, args.Result, args.Result.errorMessage))
            {

                // only bother mapping if this is the last request we sent
                if (IsGetLayerRegionsShapesInViewPendingRequest(args.Result.layerID))
                {
                    PendingGetLayerRegionsShapesInViewRequest rqst = removeGetLayerRegionsShapesInViewPendingRequest(args.Result.layerID);
                    GetLayerRegionsShapesInView(rqst.iZoomLevel, rqst.layerID, rqst.viewWindow);
                }
                else
                {
                    RaiseGetLayerRegionsShapesInViewCompleted(this, args.Result);

                    GetLayerRegionsDataInView(args.Result.layerID, args.Result.regionList);
                }

            }
        }

        private static void RaiseGetLayerRegionsShapesInViewCompleted(object sender, LayerRegionsShapesSTO sto)
        {
            if (GetLayerRegionsShapesInViewCompleted != null)
            {
                GetLayerRegionsShapesInViewCompleted(sto);
            }
            else
            {
                // todo: Log this error
                throw (new NotImplementedException("No Subscribers to GetLayerRegionsShapesInViewCompleted Event"));
            }
        }

        public int getLayerRegionsShapesInViewRequestActiveCount
        {
            get { return GetLayerRegionsShapesInViewCountByLayer.Count; }

        }

        private Dictionary<int, int> GetLayerRegionsShapesInViewCountByLayer = new Dictionary<int, int>();
        private void incrementGetLayerRegionsShapesInViewActiveCount(int layerID)
        {
            if (GetLayerRegionsShapesInViewCountByLayer.ContainsKey(layerID))
            {
                GetLayerRegionsShapesInViewCountByLayer[layerID] = GetLayerRegionsShapesInViewCountByLayer[layerID] + 1;
            }
            else
            {
                GetLayerRegionsShapesInViewCountByLayer.Add(layerID, 1);
            }
            NotifyPropertyChanged("getLayerRegionsShapesInViewRequestActiveCount");
        }
        private void decrementGetLayerRegionsShapesInViewActiveCount(int layerID)
        {
            if (GetLayerRegionsShapesInViewCountByLayer.ContainsKey(layerID))
            {
                GetLayerRegionsShapesInViewCountByLayer[layerID] = GetLayerRegionsShapesInViewCountByLayer[layerID] - 1;
                if (GetLayerRegionsShapesInViewCountByLayer[layerID] == 0)
                {
                    GetLayerRegionsShapesInViewCountByLayer.Remove(layerID);
                }
            }
            else
            {
                // it's not in the list and we don't want it there, so don't do anything
                // however, we did expect something there so there is a problem
                Log.HandleInternalError("Error decrementing count of pending GetLayerRegionsShapesInView requests, current count not found");
            }
            NotifyPropertyChanged("getLayerRegionsShapesInViewRequestActiveCount");
        }
        private int getGetLayerRegionsShapesInViewCount(int layerID)
        {
            if (GetLayerRegionsShapesInViewCountByLayer.ContainsKey(layerID))
            {
                return GetLayerRegionsShapesInViewCountByLayer[layerID];
            }
            else
            {
                return 0;
            }
        }

        public int getLayerRegionsShapesInViewRequestPendingCount
        {
            get { return pendingGetLayerRegionsShapesInViewRequests.Count; }
        }

        private Dictionary<int, PendingGetLayerRegionsShapesInViewRequest> pendingGetLayerRegionsShapesInViewRequests = new Dictionary<int, PendingGetLayerRegionsShapesInViewRequest>();
        private void addGetLayerRegionsShapesInViewPendingRequest(int layerID, PendingGetLayerRegionsShapesInViewRequest pendingRequest)
        {
            if (pendingGetLayerRegionsShapesInViewRequests.ContainsKey(layerID))
            {
                pendingGetLayerRegionsShapesInViewRequests[layerID] = pendingRequest;

            }
            else
            {
                pendingGetLayerRegionsShapesInViewRequests.Add(layerID, pendingRequest);
            }
            NotifyPropertyChanged("getLayerRegionsShapesInViewRequestPendingCount");
        }
        private PendingGetLayerRegionsShapesInViewRequest removeGetLayerRegionsShapesInViewPendingRequest(int layerID)
        {
            if (pendingGetLayerRegionsShapesInViewRequests.ContainsKey(layerID))
            {
                PendingGetLayerRegionsShapesInViewRequest pendingRequest = pendingGetLayerRegionsShapesInViewRequests[layerID];
                pendingGetLayerRegionsShapesInViewRequests.Remove(layerID);
                NotifyPropertyChanged("getLayerRegionsShapesInViewRequestPendingCount");
                return pendingRequest;
            }
            else
            {
                // it's not in the list and we don't want it there, so don't do anything
                // however, we did expect something there so there is a problem
                Log.HandleInternalError("Error decrementing count of pending GetLayerRegionsShapesInView requests, current count not found");
                return new PendingGetLayerRegionsShapesInViewRequest();
            }


        }
        private bool IsGetLayerRegionsShapesInViewPendingRequest(int layerID)
        {
            if (pendingGetLayerRegionsShapesInViewRequests.ContainsKey(layerID))
            {
                return true;
            }
            else
            {
                return false;
            }
        }


    }
}
